WR.util.namespace('WR.ui.PhotoWall');

/**
 * Photo wall item editor
 *
 * @param {Object} config
 */
WR.ui.PhotoWall.ItemEditor = function(config) {
    $.extend(this, config);

    // Post-process languages
    this.languages = new WR.data.Collection(this.languages);
    if (!this.currentLanguage && this.languages.getLength())
        this.currentLanguage = this.languages.get(0).id;

    // this.wall should be already set in constructor!
    // Bad parody on event dispatching :)
    this.addItemBehavior();
};

WR.ui.PhotoWall.ItemEditor.prototype = {
    editorTemplate: new WR.util.Template(
        '<div class="wr-item-editor">' +
            '<form method="post" class="wr-title-edit-form"></form>' +
            '<a href="#accept" class="wr-accept-button"></a>' +
            '<a href="#cancel" class="wr-cancel-button"></a>' +
        '</div>'
    ),
    simpleFieldTemplate: new WR.util.Template('<input type="text" name="title" />'),
    i18nFieldTemplate: new WR.util.Template(
        '<label>' +
            '<span>{{ title }}</span>' +
            '<input type="text" name="title_{{ id }}" />' +
        '</label>'
    ),
    toolbarTemplate: new WR.util.Template(
        '<div class="wr-item-toolbar">' +
            '<a  href="#edit-item" class="wr-edit-button"></a>' +
        '</div>'
    ),

    // Editor languages. read-only!
    // Will be converted to {WR.data.Collection} inside constructor
    // But should be set as array in config. E.g.: [{ id: "en", title: "English" }, { id: "fr", title: "Franch" }]
    languages: [
        { id: "en", title: "English" },
        { id: "ru", title: "\u0420\u0443\u0441\u0441\u043A\u0438\u0439" },
        { id: "uk", title: "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430" }
    ],
    // Current language. Will be taken the first one by default
    currentLanguage: null,

    editor: null,
    toolbar: null,

    // Private properties
    wall: null,
    rendered: false,

    render: function() {
        if (!this.rendered && this.wall) {
            var self = this;

            this.toolbar = $(this.toolbarTemplate.apply());
            this.editor = $(this.editorTemplate.apply());

            var wrapMethod = function(methodName) {
                return function(e) { e.preventDefault(); self[methodName](); }
            };
            var stopPropagation = function(e) { e.stopPropagation(); };

            this.toolbar.find('.wr-edit-button').click(wrapMethod('edit'));
            this.editor.find('.wr-accept-button').click(wrapMethod('accept'));
            this.editor.find('.wr-cancel-button').click(wrapMethod('close'));

            var form = this.editor.find('form').submit(wrapMethod('accept'));
            if (this.languages.getLength()) {
                this.languages.each(function() {
                    form.append(self.i18nFieldTemplate.apply(this));
                });
            } else {
                form.append(this.simpleFieldTemplate.apply());
            }

            $(this.wall.el).click(wrapMethod('close'));
            this.toolbar.click(stopPropagation);
            this.editor.click(stopPropagation);

            this.rendered = true;

            // Rendering part is moved to this.addItemBehavior - to handle item's late adding to the wall
        }
    },

    /**
     * This method runs just after some wall item (photo or category) is rendered
     * Bad parody on event dispatching :)
     */
    addItemBehavior: function() {
        if (!this.wall)
            return;

        var self = this;

        // Reserving old handler this.wall.afterItemRender
        var oldMethod = this.wall.afterItemRender;

        // Wrapping old handler
        // This method will run just after some wall item (photo or category) is rendered
        this.wall.afterItemRender = function() {
            // this {WR.ui.PhotoWall.Photo/WR.ui.PhotoWall.Category}
            var item = this;

            this.el.hover(
                    function() {
                        if (!self.wall.editable)
                            return;

                        if (this == self.currentItem)
                            return;

                        self.toolbar.detach().appendTo(this).show();
                        self.nextItem = this;
                    },
                    function() {
                        self.toolbar.detach();
                    }
                )
                .dblclick(function(e) {
                    if (!self.wall.editable)
                        return;

                    e.preventDefault();
                    self.edit();
                });

            return oldMethod.apply(this, arguments);
        }
    },

    edit: function() {
        if (this.wall.zoom !== 1)
            this.wall.setZoom(1);

        // Cancel previous editing
        this.close();

        this.currentItem = this.nextItem;
        var it = $(this.currentItem);

        // Temporary moving item to top
        this.currentItemZIndex = it.css('z-index');
        it.css('z-index', this.wall.zIndexMaximum + 1000);

        // Hide item toolbar
        this.toolbar.detach();

        var data = it.data('object') || {};
        if (it.is('.wr-photo-item')) {
            // We are editing photo item, thus we are putting editor into item's description element
            it = it.find('.wr-photo-description').show();
        } else {
            // We are editing category item, thus we fixating its width
            it.width(it.width());
        }

        var self = this, ed = this.editor.appendTo(it.empty());
        if (this.languages.getLength()) {
            this.languages.each(function() {
                var n = 'title_' + this.id, f = ed.find('input[name=' + n + ']');
                f.val(data[n] || '');
                if (this.id == self.currentLanguage)
                    f.focus();
            });
        } else {
            ed.find('input[name=title]').focus().val(data.title || '');
        }

        return this;
    },

    accept: function() {
        var item = $(this.currentItem).data('object');

        if (item) {
            var self = this, ed = this.editor;
            var params = {};

            if (this.languages.getLength()) {
                this.languages.each(function() {
                    var n = 'title_' + this.id, f = ed.find('input[name=' + n + ']');
                    params[n] = f.val();
                    if (this.id == self.currentLanguage)
                        params['title'] = params[n];    
                });
            } else {
                params['title'] = ed.find('input[name=title]').val();
            }
            
            item.change(params);
        }


        this.close();

        return this;
    },

    close: function() {
        // Hide item editor
        this.editor.detach();

        var it = $(this.currentItem),
            data = it.data('object') || {};

        // Restoring original item's z-index
        it.css('z-index', this.currentItemZIndex);
        delete this.currentItemZIndex;

        if (it.is('.wr-photo-item')) {
            // We are editing photo item, thus we should hide its empty description
            it = it.find('.wr-photo-description');
            if (!data.title)
                it.hide();
        } else {
            // We are editing category item, thus we making its width - automatic
            it.width('auto');
        }

        // Restoring old item title
        it.html(data.title || '');

        delete this.currentItem;

        return this;
    }
};
